package org.spring.utils;

import java.util.Arrays;

/**
 * 杂项对象实用方法。
 * <p>
 * 主要供框架内部使用。
 *
 * @author 李坤
 * @date 2022/4/19 17:17
 */
public abstract class ObjectUtils {

    /**
     * 确定给定对象是否相等，如果两者都是 {@code null}，则返回 {@code true}；如果只有一个是 {@code null}，则返回 {@code false}。
     * <p>
     * 将数组与 {@code Arrays.equals} 进行比较，基于数组元素而不是数组引用执行相等检查。
     *
     * @param obj1 第一个要比较的对象
     * @param obj2 第二个要比较的对象
     *
     * @return 给定的对象是否相等
     *
     * @see Object#equals(Object)
     * @see Arrays#equals
     */
    public static boolean nullSafeEquals(Object obj1, Object obj2) {
        if (obj1 == obj2) {
            return true;
        }
        if (obj1 == null || obj2 == null) {
            return false;
        }
        if (obj1.equals(obj2)) {
            return true;
        }
        if (obj1.getClass().isArray() && obj2.getClass().isArray()) {
            return ObjectUtils.arrayEquals(obj1, obj2);
        }
        return false;
    }

    /*--------------------------------------------------private methods-----------------------------------------------*/

    /**
     * 将给定的数组与 {@code Arrays.equals} 进行比较，基于数组元素而不是数组引用执行相等性检查。
     *
     * @param obj1 第一个要比较的数组
     * @param obj2 要比较的第二个数组
     *
     * @return 给定的对象是否相等
     *
     * @see #nullSafeEquals(Object, Object)
     * @see Arrays#equals
     */
    private static boolean arrayEquals(Object obj1, Object obj2) {
        if (obj1 instanceof Object[] && obj2 instanceof Object[]) {
            return Arrays.equals((Object[]) obj1, (Object[]) obj2);
        }
        if (obj1 instanceof boolean[] && obj2 instanceof boolean[]) {
            return Arrays.equals((boolean[]) obj1, (boolean[]) obj2);
        }
        if (obj1 instanceof byte[] && obj2 instanceof byte[]) {
            return Arrays.equals((byte[]) obj1, (byte[]) obj2);
        }
        if (obj1 instanceof char[] && obj2 instanceof char[]) {
            return Arrays.equals((char[]) obj1, (char[]) obj2);
        }
        if (obj1 instanceof double[] && obj2 instanceof double[]) {
            return Arrays.equals((double[]) obj1, (double[]) obj2);
        }
        if (obj1 instanceof float[] && obj2 instanceof float[]) {
            return Arrays.equals((float[]) obj1, (float[]) obj2);
        }
        if (obj1 instanceof int[] && obj2 instanceof int[]) {
            return Arrays.equals((int[]) obj1, (int[]) obj2);
        }
        if (obj1 instanceof long[] && obj2 instanceof long[]) {
            return Arrays.equals((long[]) obj1, (long[]) obj2);
        }
        if (obj1 instanceof short[] && obj2 instanceof short[]) {
            return Arrays.equals((short[]) obj1, (short[]) obj2);
        }
        return false;
    }

}
